package org.monster.context.core.manager;

import org.monster.context.core.ApplicationCompiler;
import org.monster.context.core.ApplicationFile;
import org.monster.context.core.ConfigContext;
import org.monster.context.core.WebAppsFile;
import org.monster.context.exception.FileException;
import org.monster.context.util.StringUtils;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * 应用管理器
 * webapp项目管理管理对象 /-->Manager//-->>FileOperator
 *
 * @author Monster
 */
public class AppsManager {

    /**
     * 日志器
     */
    private static final Logger logger = Logger.getLogger(AppsManager.class.getName());
    /**
     * 配置上下文
     */
    private final ConfigContext config;
    /**
     * 网应用文件
     */
    private final WebAppsFile apps = new WebAppsFile();
    /**
     * 应用文件
     */
    private final ApplicationFile archives = new ApplicationFile();

    /**
     * 构造方法
     */
    public AppsManager(ConfigContext config) {
        this.config = config;
    }

    /**
     * 编译应用
     * 重新编译classes
     *
     * @param appName 应用名称
     */
    public void compileApp(String appName) {
        long startTime = System.currentTimeMillis();
        File app = apps.findAppFolder(appName);
        List<File> filePaths = apps.enteringFileUnder(app);
        // 验证项目是否有效
        apps.isContainsAppFileNotClear();
        List<File> javaFiles = apps.filterSuffix(filePaths,
                Constants.JAVA_SUFFIX);
        String target = apps.generateCompiledFolder(app);
        String classPath = generateClassPath(appName).toString();
        for (File javaFile : javaFiles) {
            ApplicationCompiler.compile(target, javaFile.getAbsolutePath(),
                    classPath);
        }
        logger.log(Level.INFO, "编译WebApp，时间：{0}",
                (System.currentTimeMillis() - startTime));

    }

    /**
     * 生成 类路径
     * 生成编译所需引用的classpath
     *
     * @param webAppName 网应用名
     * @return 类路径
     */
    private StringBuffer generateClassPath(String webAppName) {
        String libPath = ApplicationFile.getLibPath(webAppName);
        String contextLibPath = ApplicationFile.getApplicationLibPath();
        StringBuffer buffer = new StringBuffer();
        buffer.append(libPath).append(";").append(contextLibPath).append(";");
        archives.getLibPathJars();
        archives.getJarPaths(webAppName);
        String property = System.getProperty("java.home");
        String toolJarPath = StringUtils.lastKeyEnds(File.separator, property)
                + File.separator + "lib" + File.separator + "tool.jar";
        buffer.append(toolJarPath).append(";");
        List<String> paths = archives.getSrcPathUnder(webAppName);
        for (String str : paths) {
            buffer.append(str).append(";");
        }
        return buffer;
    }

    /**
     * 录入应用
     *
     * @param path 路径
     */
    public void enteringApp(String path) {
        try {
            if (apps.existsFileQuote(path)) {
                String appName = apps.endsWithFileName(path);
                File file = new File(org.monster.context.core.Constants.APPS_PATH,
                        appName);
                file.mkdir();
                List<File> files = apps.enteringFileUnder(new File(path));
                apps.addFiles(files, appName, file);
                config.clearConfig();
                config.notInitFilter();
            }
        } catch (IOException | FileException ex) {
            logger.log(Level.INFO, null, ex);
        }
    }

    /**
     * 删除应用
     *
     * @param appName 应用名
     */
    public void removeApp(String appName) {
        try {
            String appPath = ApplicationFile.getAppPath(appName);
            File file = new File(appPath);
            if (file.exists()) {
                List<File> files = apps.scanFileUnder(file);
                apps.removeFiles(files);
                file.delete();
                config.clearConfig();
                config.notInitFilter();
            }
        } catch (FileException ex) {
            logger.log(Level.INFO, null, ex);
        }
    }

    /**
     * 编译初始化 应用
     */
    public void compiledInitApp() {
        long startTime = System.currentTimeMillis();
        config.clearConfig();
        config.initFilter();
        logger.log(Level.INFO, "再次初始化服务器， 时间：{0}",
                (System.currentTimeMillis() - startTime));
    }
}
